package org.smart4j.framework.common.bean;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.smart4j.framework.common.constant.ConfigConstant;
import org.smart4j.framework.common.util.CastUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 封装请求参数
 *
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-01-30 20:28
 */
public class Param {
    private List<FormParam> formParamList;

    private List<FileParam> fileParamList;

    public Param(List<FormParam> formParamList) {
        this.formParamList = formParamList;
    }

    public Param(List<FormParam> formParamList, List<FileParam> fileParamList) {
        this.formParamList = formParamList;
        this.fileParamList = fileParamList;
    }

    /**
     * 获取请求参数映射集合
     *
     * @return Map集合
     */
    public Map<String, Object> getFormMap() {
        return this.formParamList.stream().collect(Collectors.toMap(FormParam::getFieldName, FormParam::getFieldValue,
                //如果Key冲突时，会调用该函数进行将原值与新值进行分割
                (sourceValue, newValue) -> sourceValue + ConfigConstant.SEPARATOR + newValue));
    }

    /**
     * 获取上传文件关系映射
     *
     * @return Map集合
     */
    public Map<String, List<FileParam>> getFileMap() {
        Map<String, List<FileParam>> fileMap = new HashMap<>(16);
        if (CollectionUtils.isEmpty(this.fileParamList)) {
            return Maps.newHashMap();
        }
        for (FileParam fileParam : this.fileParamList) {
            String key = fileParam.getFieldName();
            if (fileMap.containsKey(key)) {
                List<FileParam> fileParams = fileMap.get(key);
                fileParams.add(fileParam);
            } else {
                fileMap.put(key, Lists.newArrayList(fileParam));
            }
        }
        return fileMap;
    }

    /**
     * 获取指定字段名的所有上传文件
     *
     * @param fieldName 字段名
     * @return List集合
     */
    public List<FileParam> getFileList(String fieldName) {
        Map<String, List<FileParam>> fileMap = this.getFileMap();
        if (MapUtils.isEmpty(fileMap)) {
            return Lists.newArrayList();
        }
        return fileMap.get(fieldName);
    }

    /**
     * 获取指定字段名的单个文件
     *
     * @param fieldName 字段名
     * @return
     */
    public Optional<FileParam> getFile(String fieldName) {
        List<FileParam> fileList = this.getFileList(fieldName);
        if (CollectionUtils.isEmpty(fileList) || fileList.size() != 1) {
            return Optional.empty();
        }
        return Optional.ofNullable(fileList.get(0));
    }

    public static void main(String[] args) {
        List<FormParam> formParamList = new ArrayList<>();
        List<FileParam> fileParamList = new ArrayList<>();
        Param param = new Param(formParamList, fileParamList);

        formParamList.add(new FormParam("test", 1));
        formParamList.add(new FormParam("test", 2));
        formParamList.add(new FormParam("test", 3));
        formParamList.add(new FormParam("test2", 0));
        System.out.println(param.getFormMap());

        FileParam fileA = new FileParam();
        fileA.setFieldName("a");
        fileA.setFileName("File A");
        fileParamList.add(fileA);
        FileParam fileB = new FileParam();
        fileB.setFieldName("a");
        fileB.setFileName("File B");
        fileParamList.add(fileB);
        FileParam fileC = new FileParam();
        fileC.setFieldName("c");
        fileC.setFileName("File C");
        fileParamList.add(fileC);
        System.out.println(param.getFileMap());
    }

    /**
     * 根据参数名获取long型参数值
     *
     * @param fieldName 指定参数名
     * @return 转换后long型值
     */
    public long getLong(String fieldName) {
        return CastUtil.castLong(this.getFormMap().get(fieldName));
    }

    /**
     * 根据参数名获取String型参数值
     *
     * @param fieldName 指定参数名
     * @return 转换后String型值
     */
    public String getString(String fieldName) {
        return CastUtil.castString(this.getFormMap().get(fieldName));
    }

    /**
     * 根据参数名获取double型参数值
     *
     * @param fieldName 指定参数名
     * @return 转换后double型值
     */
    public double getDouble(String fieldName) {
        return CastUtil.castDouble(this.getFormMap().get(fieldName));
    }

    /**
     * 根据参数名获取int型参数值
     *
     * @param fieldName 指定参数名
     * @return 转换后int型值
     */
    public int getInt(String fieldName) {
        return CastUtil.castInt(this.getFormMap().get(fieldName));
    }

    /**
     * 根据参数名获取boolean型参数值
     *
     * @param fieldName 指定参数名
     * @return 转换后boolean型值
     */
    public boolean getBoolean(String fieldName) {
        return CastUtil.castBoolean(this.getFormMap().get(fieldName));
    }

    /**
     * 判断是否有参数
     *
     * @return true 有参 false 无参
     */
    public boolean isEmpty() {
        return CollectionUtils.isEmpty(this.formParamList) && CollectionUtils.isEmpty(this.fileParamList);
    }
}
